﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reactive;
using Microsoft.WindowsAzure.StorageClient;
using System.Reactive.Linq;
using System.Diagnostics.Contracts;
using System.IO;

namespace Microsoft.WindowsAzure.StorageClient
{
    public static class CloudBlobExtensions
    {
        /// <summary>
        /// Commits the blob asynchronous.
        /// </summary>
        /// <param name="stream">The blob.</param>
        /// <returns>Asynchronous operation.</returns>
        public static IObservable<Unit> CommitAsync(this BlobStream stream)
        {
            Contract.Requires(stream != null);
            var commit = Observable.FromAsyncPattern(stream.BeginCommit, stream.EndCommit);
            return Observable.Defer(commit);
        }

        /// <summary>
        /// Updates the blob's properties asynchronous.
        /// </summary>
        /// <param name="stream">The blob.</param>
        /// <returns>Asynchronous operation.</returns>
        public static IObservable<Unit> SetPropertiesAsync(this CloudBlob blob)
        {
            Contract.Requires(blob != null);
            var setProperties = Observable.FromAsyncPattern(blob.BeginSetProperties, blob.EndSetProperties);
            return Observable.Defer(setProperties);
        }


        /// <summary>
        /// Uploads a stream to a block blob asynchronous.
        /// </summary>
        /// <param name="stream">The blob.</param>
        /// <param name="blob">The stream providing the blob content.</param>
        /// <returns>Asynchronous operation.</returns>
        public static IObservable<Unit> UploadFromStreamAsync(this CloudBlob blob, Stream stream)
        {
            Contract.Requires(blob != null);
            Contract.Requires(stream != null);

            var uploadFromStream = Observable.FromAsyncPattern<Stream>(blob.BeginUploadFromStream, blob.EndUploadFromStream);
            return Observable.Defer(() => uploadFromStream(stream));
        }
    }
}
